/*!
 *    This program is free software; you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation; either version 2 of the License, or
 *    (at your option) any later version.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with this program; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 *
 *    Author: flareguner
 *    E-Mail: flareguner@gmail.com
 *    Years: 2010-2011
 */


#include "exceptions.h"
#include "src/platform.h"
#include <QtGui/QPushButton>
#include <QtGui/QGroupBox>
#include <QtGui/QListWidget>
#include <QtGui/QDialogButtonBox>
#include <QtGui/QVBoxLayout>
#include <QtGui/QHBoxLayout>
#include <QtGui/QInputDialog>
#include <QtGui/QIcon>
#include <QtGui/QMessageBox>
#include <QtCore/QEvent>
#include <QtCore/QDebug>



// This is splitter for store sequences in fine
const QString Exceptions::m_splitter = "<->";
// This is word tag
//const QString Exceptions::m_prefix = "123_tag";

Exceptions::Exceptions(QWidget *parent) :
    QDialog(parent),
    m_flag_changed(false)
{
    createUi();
    load();



    connect(addButton, SIGNAL(clicked()),this,SLOT(addSeq()));
    connect(deleteButton, SIGNAL(clicked()),this,SLOT(deleteSeq()));
    connect(clearButton, SIGNAL(clicked()),this,SLOT(clearSeq()));
    connect(dialogButtons, SIGNAL(accepted()), this, SLOT(acceptDialog()));
    connect(dialogButtons, SIGNAL(rejected()),this,SLOT(reject()));
}

Exceptions::~Exceptions() {
    delete addButton;
    delete deleteButton;
    delete clearButton;
    delete exceptionsList;
    delete horizontalFrame;
    delete dialogButtons;
    delete centralLayout;
    delete buttonsLayout;
    delete mainLayout;
}

void Exceptions::add(const QString &seq) {
    if(!seq.isEmpty()) {
        m_exceptions_list.append(seq);
	exceptionsList->addItem(seq);
	save();
    }
}


QString Exceptions::processSourceText(const QString &text) {

    /*
      TODO: available bug: words separated by '-'
      will translated anyway. Possible solution:
      replace '-' to special codes, and replace
      it in processResultText again to normal char,maybe.
      I'm rly worry about perfomance. Must try this later.
      UPD:
      This class must use normal crypt sys. Idea:
      use base64
     */

    QString tmp = text;
    if(!tmp.isEmpty()) {
	for(int i = 0; i < m_exceptions_list.size(); i++) {

            QByteArray arr;
            arr.append(m_exceptions_list.at(i));
//	    const QString current_seq = m_exceptions_list.at(i);
            tmp = tmp.replace(arr, arr.toBase64(),
			      m_flag_cs ? Qt::CaseSensitive :
					  Qt::CaseInsensitive);
	}
    }
    return tmp;
}

QString Exceptions::processResultText(const QString &text) {
    QString tmp = text;
    if(!tmp.isEmpty()) {
	for(int i = 0; i < m_exceptions_list.size(); i++) {
//	    const QString current_seq = m_exceptions_list.at(i);
            QByteArray arr;
            arr.append(m_exceptions_list.at(i));
            tmp = tmp.replace(arr, QByteArray::fromBase64(arr),
			      m_flag_cs ? Qt::CaseSensitive :
					  Qt::CaseInsensitive);
	}
    }
    return tmp;
}

void Exceptions::acceptDialog() {
    if(m_flag_changed) {
	const int code = QMessageBox::question(this,
					   tr("Save chanes?"),
					   tr("Do you want save chanhes?"),
					   QMessageBox::Yes | QMessageBox::No);
	if(code == QMessageBox::Yes)
	    save();
    }
    this->accept();
}

void Exceptions::createUi() {
    // Buttons
    addButton = new QPushButton(/*tr("Add"),*/ this);
    deleteButton  = new QPushButton(/*tr("Delete"),*/ this);
    clearButton = new QPushButton(/*tr("Clear"),*/ this);

    buttonsLayout = new QHBoxLayout;
    buttonsLayout->addWidget(addButton);
    buttonsLayout->addWidget(deleteButton);
    buttonsLayout->addWidget(clearButton);

    // List
    exceptionsList = new QListWidget(this);
    centralGroupBox = new QGroupBox(tr("List"), this);
    centralLayout = new QVBoxLayout;
    centralLayout->addWidget(exceptionsList);
    centralGroupBox->setLayout(centralLayout);

    // Frame
    horizontalFrame = new QFrame(this);
    horizontalFrame->setFrameShape(QFrame::HLine);
    horizontalFrame->setFrameShadow(QFrame::Sunken);

    // Dialog buttons
    dialogButtons = new QDialogButtonBox(this);
    dialogButtons->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
    // And main layout
    mainLayout = new QVBoxLayout;
    mainLayout->addWidget(centralGroupBox);
    mainLayout->addLayout(buttonsLayout);
    mainLayout->addWidget(horizontalFrame);
    mainLayout->addWidget(dialogButtons);

    // Setp main layout to this window
    this->setLayout(mainLayout);


    addButton->setIcon(QIcon::fromTheme("list-add"));
    deleteButton->setIcon(QIcon::fromTheme("list-remove"));
    clearButton->setIcon(QIcon::fromTheme("edit-clear"));
}

void Exceptions::changeEvent(QEvent *e) {
    if(e->type() == QEvent::LanguageChange) {
	this->setWindowTitle(QDialog::tr("QGoogleTranslator - Exceptions"));
	addButton->setText(QPushButton::tr("Add"));
	deleteButton->setText(QPushButton::tr("Delete"));
	clearButton->setText(QPushButton::tr("Clear"));
    }
}

void Exceptions::updateButtons() {
    bool e = m_exceptions_list.isEmpty();
    deleteButton->setDisabled(e);
    clearButton->setDisabled(e);
}

void Exceptions::addSeq() {
    const QString seq = QInputDialog::getText(this,0,0);
    if(!seq.isEmpty()) {
	m_exceptions_list.append(seq);
	exceptionsList->addItem(seq);
	m_flag_changed = true;
    }
}

void Exceptions::deleteSeq() {
    const int index = exceptionsList->currentRow();
    if(! index < 0) {
	m_exceptions_list.removeAt(index);
	//! Warning: check this fragment!
	exceptionsList->removeItemWidget(exceptionsList->currentItem());
	m_flag_changed = true;
	updateButtons();
    }
}

void Exceptions::clearSeq() {
    m_exceptions_list.clear();
    exceptionsList->clear();
    updateButtons();
    m_flag_changed = true;
}

void Exceptions::load() {
    QFile file(Platform::getExceptionsPath());
    if(file.open(QFile::Text | QFile::ReadOnly)) {
	clearSeq();
	const QString data = file.readAll();
	m_exceptions_list = data.split(m_splitter);
	exceptionsList->addItems(m_exceptions_list);
	file.close();
    } else {
	qWarning() << tr("Warning! Cannot read file with exceptions: ")
		   << file.fileName()
		   << tr(" Reason:")
		   << file.errorString();
    }
}

void Exceptions::save() {
    QFile file(Platform::getExceptionsPath());
    if(file.open(QFile::Text | QFile::ReadWrite | QFile::Truncate)) {
	QByteArray data;
	data.append(m_exceptions_list.join(m_splitter));
	file.write(data);
	file.close();
    } else {
	qWarning() << tr("Error! Cannot write to exceptions file :")
		   << file.fileName()
		   << tr(" Reason :")
		   << file.errorString();
    }
}
